import 'package:sl_fast_dev/sl_fast_dev.dart';
import 'package:sl_fast_dev/src/dao/sl_container.dart';
import 'package:sl_fast_dev/src/dao/sl_node.dart';
import 'package:sl_fast_dev/src/kits/sl_objc.dart';
import 'package:sl_fast_dev/src/template/sl_templete.dart';
import 'package:sl_fast_dev/src/utils/sl_consts.dart';

class SLContainerFactory {
  String content;
  SLNode mainNode;

  SLContainer container;
  SLNodeFor nodeFor;

  Map docleverMap;

  SLContainerFactory(
    this.container,
    this.content,
    this.nodeFor, {
    this.docleverMap,
  }) {
    mainNode = transformNode(container);
  }

  String generate() {
    checkVM();

    replace_date();
    replace_class_desc();
    replace_class_name();
    replace_class_type();

    replace_h_import();
    replace_h_properties();

    replace_m_protocal();
    replace_m_addSubView();
    replace_m_layout();
    replace_m_cell_delegate();
    replace_m_properties_get();

    replace_vm_type();
    replace_vm_rac_bind();
    replace_vm_property_init();
    replace_vm_property_dis();
    replace_vm_mtd_def();
    replace_vm_mtd_invoke();

    if (mainNode.nodeFor == SLNodeFor.SLNodeForVC) {
      replace_vc();
    }

    if (mainNode.isRoot && SLFastDevConfig().docToRAC) replace_doclever();

    clearAllTags();

    return content;
  }

  SLNode transformNode(SLContainer containerT) {
    var retNode = containerT.node;

    retNode.nodeFor = nodeFor;

    if (retNode.hasChildren()) {
      retNode.children.forEach((element) {
        element.nodeFor = nodeFor;
      });
    }

    for (var i = 0; i < containerT.headers.length; i++) {
      containerT.headers[i].nodeFor = nodeFor;
    }

    return retNode;
  }

  /// 替换掉头文件
  void replace_h_import() {
    if (!content.contains('[IN_IMPORT]')) return;

    var replace = [];

    container.getAllHeadersStringL().forEach((el) {
      replace.add('#import "$el.h"');
    });

    if (replace.isNotEmpty) {
      content = content.replaceAll('[IN_IMPORT]', replace.join('\n'));
    }
  }

  /// 替换掉头文件
  void replace_h_properties() {
    if (!content.contains('[IN_PROPERTY]')) return;
    var replace = [];

    switch (mainNode.nodeFor) {
      case SLNodeFor.SLNodeForUI:
        {
          mainNode.children.forEach((child) {
            if (child.isPlaceholder()) return;
            replace.add(SLObject.property(child, mainNode));
          });
          break;
        }
      case SLNodeFor.SLNodeForVM:
        {
          mainNode.children.forEach((child) {
            if (child.isPlaceholder()) return;
            if (child.canBindRAC()) {
              replace.add(SLObject.property(child, mainNode));
              if (child.type == SLNodeType.UIButton) {
                replace.add(SLObject.propertyVM(child, mainNode));
              }
            } else if (child.isUITableView()) {
              child.getAllUITableViewCells().forEach((cell) {
                replace.add(
                    SLObject.propertyList(cell.nameList(), cell.viewModel()));
              });
            }
          });
          break;
        }
      default:
    }

    if (replace.isNotEmpty) {
      content = content.replaceAll('[IN_PROPERTY]', replace.join('\n'));
    }
  }

  /// 替换掉头文件
  void replace_date() {
    content = content.replaceAll('[DATE]', container.date);
  }

  /// 替换掉头文件
  void replace_class_name() {
    content = content.replaceAll('[IN_NAME]', mainNode.clsName());
  }

  /// 替换掉头文件
  void replace_class_desc() {
    var desc = '${mainNode.clsName()} ${mainNode.desc}';
    content = content.replaceAll('[IN_DESC]', desc);
  }

  /// 替换掉头文件
  void replace_class_type() {
    content = content.replaceAll('[IN_TYPE]', mainNode.type);
  }

  /// 替换掉头文件
  void replace_m_protocal() {
    if (container.protocal.isEmpty) return;

    var pro = '<${container.protocal.join(',')}>';
    content = content.replaceAll('[V_DELEGATE_NAME]', pro);
  }

  /// 替换掉头文件
  void replace_m_addSubView() {
    if (!content.contains('[V_ADD_SUB]')) return;
    if (!mainNode.hasChildren()) return;

    var replace = [];
    mainNode.children.forEach((child) {
      if (child.isPlaceholder()) return;
      replace.addAll(SLObject.sub_view(child, mainNode));
    });

    if (replace.isNotEmpty) {
      content = content.replaceAll('[V_ADD_SUB]', replace.join('\n'));
    }
  }

  /// 替换掉头文件
  void replace_m_layout() {
    if (!content.contains('[V_LAYOUT]')) return;
    if (!mainNode.hasChildren()) return;

    var replace = [];
    mainNode.children.forEach((child) {
      if (child.isPlaceholder()) return;
      replace.add(SLObject.layout(child, mainNode));
    });

    if (replace.isNotEmpty) {
      content = content.replaceAll('[V_LAYOUT]', replace.join('\n'));
    }
  }

  /// 替换掉头文件
  void replace_m_cell_delegate() {
    if (!content.contains('[V_TABLE_CELL_USE]')) return;
    var cells = mainNode.getAllChildrenCells();

    if (cells == null || cells.isEmpty) return;

    var cell = sl_table_cell;

    var cellL = [];

    var name = '';
    var cls = '';
    for (var i = 0; i < cells.length; i++) {
      cellL.add((i == 0 ? '' : '// ') + SLObject.table_cell(cells[i]));
      if (i == 0) {
        name = cells[i].nameList();
        cls = cells[i].viewModel();
      }
    }

    cell = cell.replaceAll('[CELL_USE]', cellL.join('\n'));
    if (name.isNotEmpty) {
      cell = cell.replaceAll('[CELL_USE_NAME]', name);
    }
    if (cls.isNotEmpty) {
      cell = cell.replaceAll('[CELL_USE_VM]', cls);
    }

    content = content.replaceAll('[V_TABLE_CELL_USE]', cell);
  }

  /// 替换掉头文件
  void replace_m_properties_get() {
    if (!content.contains('[V_PROPERTY_GET]')) return;
    if (!mainNode.hasChildren()) return;

    var replace = [];
    mainNode.children.forEach((child) {
      if (child.isPlaceholder()) return;
      replace.add(SLObject.property_get(child));
    });

    if (replace.isNotEmpty) {
      content = content.replaceAll('[V_PROPERTY_GET]', replace.join('\n'));
    }
  }

  /// 替换掉头文件
  void replace_vm_type() {
    content = content.replaceAll('[V_VM_TYPE]', mainNode.viewModel());
  }

  /// 替换掉头文件
  void replace_vm_rac_bind() {
    if (!content.contains('[V_VM_BIND]')) return;
    if (!mainNode.hasChildren()) return;

    var replace = [];
    mainNode.children.forEach((child) {
      if (child.isPlaceholder()) return;
      var ret = SLObject.vm_bind(child);
      if (ret.isNotEmpty) replace.add(ret);
    });

    if (replace.isNotEmpty) {
      content = content.replaceAll('[V_VM_BIND]', replace.join('\n'));
    }
  }

  /// 替换掉头文件
  void replace_vm_property_init() {
    if (!content.contains('[VM_IM_PROPERTY]')) return;
    if (!mainNode.hasChildren()) return;

    var replace = [];
    mainNode.children.forEach((child) {
      if (child.isPlaceholder()) return;
      if (child.canBindRAC()) {
        replace.add('        _${child.nameString()} = [NSString string];');
      } else if (child.isUITableView()) {
        child.getAllUITableViewCells().forEach((cell) {
          replace.add('        _${cell.nameList()} = [NSArray array];');
        });
      }
    });

    if (replace.isNotEmpty) {
      content = content.replaceAll('[VM_IM_PROPERTY]', replace.join('\n'));
    }
  }

  /// 替换掉头文件
  void replace_vm_property_dis() {
    if (!content.contains('[VM_IM_PROPERTY_DIS]')) return;
    if (!mainNode.hasChildren()) return;

    var replace = [];
    mainNode.children.forEach((child) {
      if (child.isPlaceholder()) return;
      if (child.type == SLNodeType.UIButton) {
        replace.add('    [self.${child.nameCMD()} rac_deallocDisposable];');
      }
    });

    if (replace.isNotEmpty) {
      content = content.replaceAll('[VM_IM_PROPERTY_DIS]', replace.join('\n'));
    }
  }

  /// 替换掉头文件
  void replace_vm_mtd_def() {
    if (!content.contains('[VM_IM_CMD]')) return;

    if (!mainNode.hasChildren()) return;

    var cmd = sl_mtd_RACCommand;

    var replace = [];
    mainNode.children.forEach((child) {
      if (child.isPlaceholder()) return;
      if (child.type == SLNodeType.UIButton) {
        replace.add(cmd.replaceAll('[RACCommand_NAME]', child.nameCMD()));
      }
    });

    if (replace.isNotEmpty) {
      content = content.replaceAll('[VM_IM_CMD]', replace.join('\n'));
    }
  }

  /// 替换掉头文件
  void replace_vm_mtd_invoke() {
    if (!content.contains('[VM_IM_CMD_USE]')) return;
    if (!mainNode.hasChildren()) return;

    var replace = [];
    mainNode.children.forEach((child) {
      if (child.isPlaceholder()) return;
      if (child.type == SLNodeType.UIButton) {
        replace.add('    [self seg_${child.nameCMD()}];');
      }
    });

    if (replace.isNotEmpty) {
      content = content.replaceAll('[VM_IM_CMD_USE]', replace.join('\n'));
    }
  }

  void replace_doclever() {
    if (docleverMap == null || docleverMap.keys.isEmpty) return;

    content = content.replaceAll('[DOC_MANAGER]', docleverMap['cls']);
    content = content.replaceAll('[DOC_MANAGER_NAME]', docleverMap['name']);
    content = content.replaceAll('[DOC_MANAGER_NAME]', docleverMap['name']);
    content = content.replaceAll('[DOC_MTD_DIS]', docleverMap['mtd_dis']);
    content = content.replaceAll('[DOC_MTD_INVOKE]', docleverMap['mtd_invoke']);
    content = content.replaceAll('[DOC_MTD_MTD]', docleverMap['mtd']);
    content = content.replaceAll('[DOC_PROPERTIES]', docleverMap['properties']);
    content = content.replaceAll('[DOC_RAC_SUB]', docleverMap['sub']);
  }

  /// 替换掉头文件
  void replace_vc() {
    content = content.replaceAll('[VC_V_TYPE]', mainNode.cls());
    content = content.replaceAll('[VC_V_NAME]', mainNode.property());
    content = content.replaceAll('[VC_V_INIT]',
        SLFastDevConfig().hasVM ? 'initWithViewModel:self.$vmName' : 'init');
    content = content.replaceAll('[VC_VM_TYPE]', mainNode.viewModel());
    content = content.replaceAll('[VC_VM_NAME]', vmName);
  }

  ///
  void checkVM() {
    var contentL = content.split('\n');
    var retL = [];

    contentL.forEach((line) {
      if (line.contains('[V_VM_CHECK]')) {
        if (!SLFastDevConfig().hasVM) return;
        retL.add(line.replaceAll('[V_VM_CHECK]', ''));
      } else if (line.contains('[DOC_CHECK]')) {
        if (!SLFastDevConfig().docToRAC || docleverMap.keys.isEmpty) return;
        if (!mainNode.isRoot) return;
        retL.add(line.replaceAll('[DOC_CHECK]', ''));
      } else {
        retL.add(line);
      }
    });

    content = retL.join('\n');
  }

  void clearAllTags() {
    content = content.replaceAllMapped(RegExp('\\[DOC_[(A-Z|_)]+\\]'), (match) {
      return '';
    });

    content = content.replaceAllMapped(RegExp('\\[[(A-Z|_)]+\\]'), (match) {
      return '';
    });

    content = content.replaceAllMapped(RegExp('\n\n\n'), (match) {
      return '\n\n';
    });
  }
}
